/*
		* Author:	 Sander
		* Date:		 12-apr-2011
		* Name:		 Material
		* Version:	1.0
		*
		* This code is property of Sander blahblahblah copyright blahblah.
*/


package javaraytracer.Materials;

import javaraytracer.IntersectionInfo;
import javaraytracer.Vec3;
import javaraytracer.parsers.MaterialLibrary;

//PENDING:add function/property description
public class Material
{
	// statics

	public static final Material WHITE = new Material(Vec3.ONE, Vec3.EMPTY, 0f, 0f);


	//instance

	public Vec3 colour			= Vec3.EMPTY;
	public Vec3 diffuse			= Vec3.EMPTY;
	public float reflectance	= 0f;
	public Vec3 specular		= Vec3.EMPTY;
	public float specularN		= 0f;
	public Vec3 ambient			= Vec3.EMPTY;
	public boolean drawShadow	= true;
	public boolean castShadow	= true;
	public Vec3[] offset		= {Vec3.EMPTY, Vec3.EMPTY, Vec3.EMPTY}; //uv mapping

	public Image ambientMap		= null;
	public Image diffuseMap		= null;
	public Image specularMap	= null;
	public Image specularNMap	= null;
	public Image dMap			= null;
	public Image bumpMap		= null;

	public Material(Vec3 c)
	{
		colour		= diffuse = c;
		reflectance	= 0.0f;
		specularN	= 0.2f;
		ambient		= Vec3.EMPTY;
		castShadow	= true;
		drawShadow	= true;
	}
	public Material(Vec3 c, Vec3 am, float ref, float sp)
	{
		colour		= diffuse = c;
		ambient		= am;
		reflectance	= ref;
		specularN	= sp;
		castShadow	= true;
		drawShadow	= true;
	}
	public Material(Vec3 c, Vec3 am, float ref, float sp, boolean cast)
	{
		colour		= diffuse = c;
		ambient		= am;
		reflectance	= ref;
		specularN	= sp;
		castShadow	= cast;
		drawShadow	= true;
	}
	public Material(Vec3 c, Vec3 am, float ref, float sp, boolean cast, boolean shadow)
	{
		colour		= diffuse = c;
		ambient		= am;
		reflectance	= ref;
		specularN	= sp;
		castShadow	= cast;
		drawShadow	= shadow;
	}
	public Material(Material other)
	{
		colour		= diffuse = other.colour.clone();
		ambient		= other.ambient.clone();
		reflectance	= other.reflectance;
		specular	= other.specular.clone();
		specularN	= other.specularN;
		castShadow	= other.castShadow;
		drawShadow	= other.drawShadow;
		offset		= other.offset.clone();

		ambientMap		= other.ambientMap;
		diffuseMap		= other.diffuseMap;
		specularMap		= other.specularMap;
		specularNMap	= other.specularNMap;
		dMap			= other.dMap;
		bumpMap			= other.bumpMap;
	}
	public Material(MaterialLibrary library)
	{
		colour		= diffuse = library.diffuse;
		reflectance = library.specularN / 1000;
		specular	= library.specular;
		specularN	= library.specularN;
		ambient		= library.ambient;
		castShadow	= true;
		drawShadow	= true;
		//reflectance = 0.5f;

		ambientMap		= library.ambientMap;
		diffuseMap		= library.diffuseMap;
		specularMap		= library.specularMap;
		specularNMap	= library.specularNMap;
		dMap			= library.dMap;
		bumpMap			= library.bumpMap;
	}

	public void position(IntersectionInfo info)
	{
		if(diffuseMap != null)
		{
			double b, g, r = g = b = 0.0;
			int x, y;
			
			Vec3 p1, p2, p3;

			if(offset != null && offset.length != 0)
			{
				p1 = offset[0];
				p2 = offset[1];
				p3 = offset[2];

				x = (int)((p1.x + (p2.x - p1.x) * info.u + (p3.x - p1.x) * info.v) * diffuseMap.imageWidth);
				y = (int)((1 - (p1.y + (p2.y - p1.y) * info.u + (p3.y - p1.y) * info.v)) * diffuseMap.imageHeight);
			}
			else
			{
				x = (int)((diffuseMap.imageWidth - 1.0) * info.u);
				y = (int)((diffuseMap.imageHeight- 1.0) * info.v);
			}

			r += ((diffuseMap.data[y][x] >> 16) & 0xFF);
			g += ((diffuseMap.data[y][x] >> 8) & 0xFF);
			b += (diffuseMap.data[y][x] & 0xFF);
			
			colour.x = (r / 255.0);
			colour.y = (g / 255.0);
			colour.z = (b / 255.0);
		}

		
	}

}
